package com.wmx.spring;

import com.wmx.pojo.ResultData;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.boot.system.ApplicationPid;
import org.springframework.boot.system.ApplicationTemp;
import org.springframework.boot.system.JavaVersion;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.WebUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * SpringBoot 应用常用工具类
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2024/7/7 18:02
 */
@RestController
public class SpringBootUtil {

    /**
     * 获取当前SpringBoot程序的进程号/进程ID，也就是系统'任务管理器'中的PID。
     * 知道进程号后，可以根据进程号结束进程。
     * <p>
     * http://localhost:8080/springBoot/getPid
     *
     * @return
     */
    @GetMapping("springBoot/getPid")
    public ResultData getPid() {
        Map<String, Object> dataMap = new HashMap<>();

        // 获取当前SpringBoot程序的进程号/进程ID
        // 底层使用：
        // try {
        // 		String jvmName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
        // 		return jvmName.split("@")[0];
        // } catch (Throwable ex) {
        // 		return null;
        // 	}
        ApplicationPid pid = new ApplicationPid();
        dataMap.put("pid", pid.toString());

        return ResultData.success(dataMap);
    }

    /**
     * 获取应用程序运行的主目录，即服务/程序当前的所在位置/所在目录/所在路径
     * 1、ApplicationHome 提供访问应用程序主目录的途径。尝试为Jar文件、解压缩文件和直接运行的应用程序选择一个合理的主目录。
     * <p>
     * http://localhost:8080/springBoot/getApplicationHome
     *
     * @return
     */
    @GetMapping("springBoot/getApplicationHome")
    public ResultData getApplicationHome() {
        ApplicationHome home = new ApplicationHome();
        // 返回应用程序主目录。
        File homeDir = home.getDir();
        // 返回用于查找主目录的基础源。这通常是jar文件或目录。如果无法确定源，则可以返回｛@code null｝。
        // 在IDEA中访问时会返回null，打成Jar包后会返回Jar文件路径
        File homeSource = home.getSource();
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("homeDir", homeDir.getAbsolutePath());
        dataMap.put("homeSource", homeSource == null ? "" : homeSource.getAbsolutePath());

        // IDEA中运行当前应用：D:\java\workspace\test-app
        // 输出结果：
        // homeDir: D:\java\workspace\test-app
        // homeSource: null

        // 将应用打成 jar 包后，jar包位于：D:\java\workspace\test-app\target\test-app-1.0.0.jar
        // 此时运行 jar 包，输出结果：
        // homeDir: D:\java\workspace\test-app\target
        // homeSource: D:\java\workspace\test-app\target\test-app-1.0.0.jar

        return ResultData.success(dataMap);
    }

    /**
     * 获取Java版本/Java JDK 版本
     * <p>
     * http://localhost:8080/springBoot/getJavaVersion
     *
     * @return
     */
    @GetMapping("springBoot/getJavaVersion")
    public ResultData getJavaVersion() {
        // 可以通过 JavaVersion 获取当前 SpringBoot 运行时的 java 版本
        // 可以调用 isEqualOrNewerThan 和 isOlderThan 进行java版本的比较
        JavaVersion javaVersion = JavaVersion.getJavaVersion();

        // 传统方法也可以
        String javaVersion2 = System.getProperty("java.version");

        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("javaVersion", javaVersion.toString());
        dataMap.put("javaVersion2", javaVersion2);

        // {
        //     "javaVersion": "1.8",
        //     "javaVersion2": "1.8.0_251"
        //   }
        return ResultData.success(dataMap);
    }

    /**
     * 获取 应用临时目录
     * <p>
     * http://localhost:8080/springBoot/getTempDir
     *
     * @return
     */
    @GetMapping("springBoot/getTempDir")
    public ResultData getTempDir(HttpServletRequest request) {
        // 系统默认的临时文件路径
        String tempDir1 = System.getProperty("java.io.tmpdir");
        // 返回当前web应用程序的临时目录
        File tempDir2 = WebUtils.getTempDir(request.getServletContext());

        // 提供对特定于应用程序的临时目录的访问权限。一般来说，不同的Spring Boot应用程序会得到不同的位置，然而，简单地重新启动应用程序就会得到相同的位置。
        ApplicationTemp temp = new ApplicationTemp();
        File tempDir3 = temp.getDir();

        Map<String, Object> dataMap = new LinkedHashMap<>();
        dataMap.put("tmpDir1", tempDir1);
        dataMap.put("tempDir2", tempDir2.getAbsolutePath());
        dataMap.put("tempDir3", tempDir3.getAbsolutePath());

        // {
        //     "tmpDir1": "C:\\Users\\A\\AppData\\Local\\Temp\\",
        //     "tempDir2": "C:\\Users\\A\\AppData\\Local\\Temp\\tomcat.5731382199774678364.8080\\work\\Tomcat\\localhost\\ROOT",
        //     "tempDir3": "C:\\Users\\A\\AppData\\Local\\Temp\\9024604D66CECC867307D8FB0FC6E265347AB23A"
        //   }
        return ResultData.success(dataMap);
    }

    /**
     * 获取当前应用启动类所在的基包（basePackages）
     * http://localhost:8080/springBoot/getBasePackage
     *
     * @param request
     * @return
     */
    @Resource
    private ConfigurableApplicationContext context;

    @GetMapping("springBoot/getBasePackage")
    public ResultData getBasePackage() {
        List<String> strings = AutoConfigurationPackages.get(context);
        // ["com.wmx"]
        return ResultData.success(strings);
    }


}
